#ifndef __SHADER__MANAGER__H__
#define __SHADER__MANAGER__H__
#include "common/Singleton.hpp"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include <Cg/cgGL.h>
#include <Cg/cg.h>
//#include <gl/glut.h>
#include <GL/glut.h>

#include <map>
#include <string>
#include <memory>
#include <thread>
#include "ShaderIdent.h"

typedef int PROGRAM_HANDLE;
struct ShaderProfileConfig
{
	std::string fileName;
	std::string desc;
	CGprofile profile;
	PROGRAM_HANDLE handle;
	bool shared;
};

struct ProgramData
{
	CGprogram program;
	ShaderID shaderId;
};

class ShaderManager : public FragrantGrass::Singleton<ShaderManager>
{
public:
	typedef std::shared_ptr<ShaderProfileConfig> ShaderProfileConfigPtr;
	typedef std::map<ShaderID, ShaderProfileConfigPtr> ProfileConfigMap;
	typedef std::shared_ptr<ProgramData> ProgramDataPtr;
	typedef std::map<PROGRAM_HANDLE, ProgramDataPtr> ProgramMap;

private:
	static PROGRAM_HANDLE HANDLE_ATOM;
	static PROGRAM_HANDLE INVALID_HANDLE;

public:
	ShaderManager();
	~ShaderManager();

public:
	void Initialize(CGcontext content);
	PROGRAM_HANDLE CreateShader(ShaderID id);
	void DestroyShader(PROGRAM_HANDLE handle);
	void LoadShader(PROGRAM_HANDLE handle);
	void UnLoadShader(PROGRAM_HANDLE handle);
	void EnableShaderProfile(PROGRAM_HANDLE handle);
	void DisableShaderProfile(PROGRAM_HANDLE handle);
	void BindShader(PROGRAM_HANDLE handle);
	void UnBindShader(PROGRAM_HANDLE handle);
	CGprogram GetProgram(PROGRAM_HANDLE handle);

private:
	void RegisterProfile();
	void AddShaderConfig(ShaderID id, const std::string& desc, const std::string& fileName,CGprofile profile,bool shared);

private:
	CGcontext mCgContent;
	ProfileConfigMap mProfiles;
	ProgramMap mPrograms;

};
#endif//__SHADER__MANAGER__H__